
class Process:
    def __init__(self, pid, arrival_time, burst_time):
        self.pid = pid
        self.arrival_time = arrival_time
        self.burst_time = burst_time
        self.remaining_time = burst_time
        self.waiting_time = 0
        self.turnaround_time = 0
        self.completion_time = 0

    def __repr__(self):
        return f"Process {self.pid} (Arrival: {self.arrival_time}, Burst: {self.burst_time})"

def fcfs(processes):
    sorted_processes = sorted(processes, key=lambda p: p.arrival_time)
    current_time = 0
    for p in sorted_processes:
        if current_time < p.arrival_time:
            current_time = p.arrival_time
        p.completion_time = current_time + p.burst_time
        p.turnaround_time = p.completion_time - p.arrival_time
        p.waiting_time = current_time - p.arrival_time
        current_time = p.completion_time
    return sorted_processes

def sjf_non_preemptive(processes):
    sorted_by_arrival = sorted(processes, key=lambda p: p.arrival_time)
    current_time = 0
    completed = []
    remaining = sorted_by_arrival.copy()
    while remaining:
        eligible = [p for p in remaining if p.arrival_time <= current_time]
        if not eligible:
            next_arrival = min(p.arrival_time for p in remaining)
            current_time = next_arrival
            continue
        shortest = min(eligible, key=lambda p: p.burst_time)
        shortest.waiting_time = current_time - shortest.arrival_time
        shortest.completion_time = current_time + shortest.burst_time
        shortest.turnaround_time = shortest.completion_time - shortest.arrival_time
        current_time = shortest.completion_time
        completed.append(shortest)
        remaining.remove(shortest)
    return completed

def round_robin(processes, time_quantum):
    sorted_by_arrival = sorted(processes, key=lambda p: p.arrival_time)
    queue = []
    current_time = 0
    index = 0
    processes_copy = [Process(p.pid, p.arrival_time, p.burst_time) for p in sorted_by_arrival]
    for p in processes_copy:
        p.remaining_time = p.burst_time
    while queue or index < len(processes_copy):
        while index < len(processes_copy) and processes_copy[index].arrival_time <= current_time:
            queue.append(processes_copy[index])
            index += 1
        if not queue:
            current_time = processes_copy[index].arrival_time
            continue
        current_process = queue.pop(0)
        exec_time = min(time_quantum, current_process.remaining_time)
        current_time += exec_time
        current_process.remaining_time -= exec_time
        while index < len(processes_copy) and processes_copy[index].arrival_time <= current_time:
            queue.append(processes_copy[index])
            index += 1
        if current_process.remaining_time > 0:
            queue.append(current_process)
        else:
            current_process.completion_time = current_time
            current_process.turnaround_time = current_process.completion_time - current_process.arrival_time
            current_process.waiting_time = current_process.turnaround_time - current_process.burst_time
    return processes_copy

# 测试数据
processes = [
    Process('P1', 0, 5),
    Process('P2', 1, 3),
    Process('P3', 2, 8),
    Process('P4', 3, 6)
]

# 运行调度算法
fcfs_result = fcfs([Process(p.pid, p.arrival_time, p.burst_time) for p in processes])
sjf_result = sjf_non_preemptive([Process(p.pid, p.arrival_time, p.burst_time) for p in processes])
rr_result = round_robin(processes, time_quantum=2)

# 计算平均值
def calculate_averages(processes):
    total_wait = sum(p.waiting_time for p in processes)
    total_turnaround = sum(p.turnaround_time for p in processes)
    avg_wait = total_wait / len(processes)
    avg_turnaround = total_turnaround / len(processes)
    return avg_wait, avg_turnaround

# 输出结果
print("FCFS调度结果：")
for p in fcfs_result:
    print(f"进程 {p.pid}: 等待时间={p.waiting_time}, 周转时间={p.turnaround_time}")

avg_wait_fcfs, avg_turn_fcfs = calculate_averages(fcfs_result)
print(f"FCFS平均等待时间: {avg_wait_fcfs:.2f}, 平均周转时间: {avg_turn_fcfs:.2f}\n")

print("SJF调度结果：")
for p in sjf_result:
    print(f"进程 {p.pid}: 等待时间={p.waiting_time}, 周转时间={p.turnaround_time}")

avg_wait_sjf, avg_turn_sjf = calculate_averages(sjf_result)
print(f"SJF平均等待时间: {avg_wait_sjf:.2f}, 平均周转时间: {avg_turn_sjf:.2f}\n")

print("时间片轮转调度结果：")
for p in rr_result:
    print(f"进程 {p.pid}: 等待时间={p.waiting_time}, 周转时间={p.turnaround_time}")

avg_wait_rr, avg_turn_rr = calculate_averages(rr_result)
print(f"RR平均等待时间: {avg_wait_rr:.2f}, 平均周转时间: {avg_turn_rr:.2f}")



